package com.yuanchu.store.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yuanchu.common.utils.R;
import com.yuanchu.store.client.FeignAuthClient;
import com.yuanchu.store.dto.AuthParamsDto;
import com.yuanchu.store.utils.RedisUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * @version: 1.0
 * @Author: adan
 * @description: 商家用户登录
 * @date: 2024-01-13 23:21
 */
@Api(value = "LoginController", tags = "登录接口")
@Slf4j
@RestController
public class StoreLoginController {

    @Value("${yuanchu.security.client-id}")
    private String clientId;

    @Value("${yuanchu.security.client-secret}")
    private String clientSecret;
    @Resource
    private FeignAuthClient feignAuthClient;
    @Resource
    private RedisUtils redisUtils;

    @ApiOperation(value = "登录", notes = "登录参数: username, password", httpMethod = "POST")
    @PostMapping(value = "/passport/login")
    public R login(@Validated @RequestBody AuthParamsDto authParam) {
        String username = authParam.getUsername();
        String password = authParam.getPassword();
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return R.error("请输入用户名和密码");
        }
        MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
        paramsMap.set("grant_type", "password");
        paramsMap.set("username", JSON.toJSONString(authParam));
        paramsMap.set("client_id", clientId);
        paramsMap.set("client_secret", clientSecret);
        Map<String, Object> accessToken = null;
        try {
            // POST {{auth_host}}/auth/oauth/token?client_id=XcWebApp&client_secret=XcWebApp&grant_type=password&
            //     username={"username":"adan","authType":"password","password":"123456"}
            // accessToken = feignAuthClient.postAccessToken(paramsMap);
            accessToken = feignAuthClient.postAccessToken2(paramsMap);
        } catch (Exception e) {
            log.error("获取token失败：{}", e.getMessage());
            return R.error(HttpStatus.SC_INTERNAL_SERVER_ERROR,"登入失败");
            // String message = e.getMessage();
            // // 找到JSON并提取错误信息开始的位置
            // int jsonStart = message.lastIndexOf("[") + 1;
            // int jsonEnd = message.lastIndexOf("]");
            // String jsonResponse = message.substring(jsonStart, jsonEnd);
            // // 使用Jackson解析JSON
            // ObjectMapper objectMapper = new ObjectMapper();
            // Map<String, String> errorInfo = null;
            // try {
            //     errorInfo = objectMapper.readValue(jsonResponse, new TypeReference<Map<String, String>>() {
            //     });
            // } catch (JsonProcessingException ex) {
            //     // JSON解析失败
            //     log.error("JSON解析失败：{}", ex.getMessage());
            //     throw new YuanChuException(ex.getMessage());
            // }
            // return R.error(HttpStatus.SC_INTERNAL_SERVER_ERROR, errorInfo.get("error_description"));
        }
        if (accessToken.get("code") != null){
            String formattedJsonString = JSON.toJSONString(accessToken.get("result"));
            JSONObject jsonObject = JSONObject.parseObject(formattedJsonString);
            String errorDescription = jsonObject.getString("error_description");
            return R.error(HttpStatus.SC_INTERNAL_SERVER_ERROR, errorDescription);
        }
        String token = accessToken.get("access_token").toString();
        String userId = accessToken.get("userId").toString();
        String refreshToken = accessToken.get("refresh_token").toString();
        redisUtils.set("token_"+ token, refreshToken, 604800);
        // 解析token,获取用户id
        // Claims claims = Jwts.parser().setSigningKey("mq123".getBytes(StandardCharsets.UTF_8)).parseClaimsJws(token).getBody();
        // String userNameJson = (String) claims.get("user_name");
        // YoshopStoreUserEntity user = JSON.parseObject(userNameJson, YoshopStoreUserEntity.class);
        Map<String, Object> map = new LinkedHashMap<>();
        map.put("token", token);
        map.put("userId", userId);
        return R.ok().put("data", map);
    }


    @PostMapping(value = "/passport/logout")
    public R logOut(HttpServletRequest req, HttpServletResponse resp) {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();

        String accessToken = req.getHeader("authorization");
        // String accessToken = req.getHeader("Access-Token");
        // accessToken = accessToken.replace("Bearer ", "");
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        headers.add("Content-Type","application/json;charset=utf-8");
        headers.add("Authorization",accessToken);
        feignAuthClient.outAccessToken(headers);
        return R.ok();
    }


    /*@PostMapping(value = "/pass/login")
    @ResponseBody
    public R login(@Validated @RequestBody AuthParamsDto authParam) {

        String username = authParam.getUsername();
        String password = authParam.getPassword();
        if (StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
            return R.error("请输入用户名和密码");
        }

        MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
        // MediaType.APPLICATION_FORM_URLENCODED
        // headers.add("Content-Type","multipart/form-data");
        // headers.add("Authorization","Basic");

        MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
        paramsMap.set("grant_type", "password");
        paramsMap.set("username", JSON.toJSONString(authParam));
        paramsMap.set("client_id", "XcWebApp");
        paramsMap.set("client_secret", "XcWebApp");

        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        body.add("username", JSON.toJSONString(authParam));
        // body.add("password", password);
        body.add("grant_type", "password");
        body.add("scope", "all");
        Map<String, String> accessToken = null;
        // Map<String, Object> map1 = feignAuthClient.postAccessToken(paramsMap, headers);
        try {
            // Object accessToken = feignAuthClient.postAccessToken(paramsMap, headers);
            // POST {{auth_host}}/auth/oauth/token?client_id=XcWebApp&client_secret=XcWebApp&grant_type=password&
            //     username={"username":"adan","authType":"password","password":"123456"}
            accessToken = feignAuthClient.postAccessToken(paramsMap);

        }catch (Exception e) {
            log.error("获取token失败 {}", e);
            String message = e.getMessage();
            // 找到JSON并提取错误信息开始的位置
            int jsonStart = message.lastIndexOf("[") + 1;
            int jsonEnd = message.lastIndexOf("]");
            String jsonResponse = message.substring(jsonStart, jsonEnd);
            // 使用Jackson解析JSON
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, String> errorInfo = null;
            try {
                errorInfo = objectMapper.readValue(jsonResponse, new TypeReference<Map<String, String>>(){});
            } catch (JsonProcessingException ex) {
                // JSON解析失败
                log.error("JSON解析失败 {}", ex);
                throw new YuanChuException(ex.getMessage());
            }
            // System.out.println("Error: " + errorInfo.get("error"));
            // System.out.println("Error Description: " + errorInfo.get("error_description"));
            return R.error(HttpStatus.SC_INTERNAL_SERVER_ERROR, errorInfo.get("error_description"));
        }

        // 服务内部调用 认证服务
        // Map<String, Object> map = feignAuthClient.generateToken(body);

        // log.info("获取token成功 {}", map);
        // Map<String, Object> tokenMap = new HashMap<>();
        // tokenMap.put("token", map.get("access_token"));
        // tokenMap.put("tokenHead", "");
        // return R.ok(tokenMap);
        return R.ok().put("data", accessToken);
    }*/

    /*@PostMapping("/pass/login")
    public R login(@RequestBody AuthParamsDto params, @RequestHeader HttpHeaders httpHeaders) throws UnsupportedEncodingException {
        // 构造 post的body内容（要post的内容，按需定义）
        MultiValueMap<String, String> paramsMap = new LinkedMultiValueMap<>();
        paramsMap.set("grant_type", "password");
        String username = params.getUsername();
        String jsonString = JSON.toJSONString(params);
        paramsMap.set("username", jsonString);
        String password = params.getPassword();
        paramsMap.set("client_id", clientId);
        paramsMap.set("client_secret", clientSecret);
        // paramsMap.set("password", password);


        // BASE64Decoder decoder = new BASE64Decoder();
        // try {
        //     paramsMap.set("password", new String(decoder.decodeBuffer(password)));
        // } catch (IOException e) {
        //     return R.error("密码有误");
        // }
        // 使用客户端的请求头,发起请求
        httpHeaders.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        // httpHeaders.setContentType(MediaType.APPLICATION_JSON);
        // 强制移除 原来的请求头,防止token失效
        httpHeaders.remove(HttpHeaders.AUTHORIZATION);
        //构造请求实体和头
        HttpEntity<AuthParamsDto> httpEntity = new HttpEntity<>(params, httpHeaders);
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity(paramsMap, httpHeaders);
        JSONObject authInfo = null;
        ResponseEntity<JSONObject> response = null;
        try {
            authInfo = restTemplate.postForObject(accessTokenUri, request, JSONObject.class);
            // response = restTemplate.postForEntity(accessTokenUri, httpEntity, JSONObject.class);
        } catch (HttpClientErrorException e) {
            if (e.getStatusCode().equals(HttpStatus.BAD_REQUEST)) {
                e.printStackTrace();
                byte[] bs = e.getResponseBodyAsByteArray();
                String msg = new String(bs, "utf-8");
                Map<String, String> mm = (Map<String, String>) JSON.parse(msg);
                return R.error(mm.get("error_description"));
            } else {
                return R.error("登录失败");
            }
        }
        JSONObject jsonObject = new JSONObject(authInfo);
        String jwt = jsonObject.getString("access_token");
        Map<String, String> jwtMap = new HashMap<>();
        jwtMap.put("token", jwt);
        return R.ok().put("data", jwtMap);
    }*/

}